using System.Collections;
using Unity.Mathematics;
using UnityEngine;

public class EntityFX : MonoBehaviour
{
    protected Entity entity;
    protected SpriteRenderer Sr { get; private set; }
    [Header("Flash FX")]
    [SerializeField] protected float flashDuration = 0.2f;
    protected Material hitMaterial;
    protected Material originalMaterial;
    [Header("Ailment colors")]
    [SerializeField] private Color[] chillColor;
    [SerializeField] private Color[] igniteColors;
    [SerializeField] private Color[] shockColors;
    [Header("Ailment FX")]
    protected ParticleSystem igniteFx;
    protected ParticleSystem chillFx;
    protected ParticleSystem shockFx;
    [Header("Hit FX")]
    protected GameObject hitFxPrefab;
    protected GameObject hitCriticalFxPrefab;
    [Header("Pop up")]
    protected GameObject popUpFxPrefab;
    private GameObject hpBar;

    protected virtual void Awake()
    {
        Sr = GetComponentInChildren<SpriteRenderer>();
        originalMaterial = Sr.material;
        entity = GetComponent<Entity>();
        hpBar = GetComponentInChildren<UiHpBar>().gameObject;
        hitCriticalFxPrefab = Resources.Load<GameObject>("Prefabs/Fx/Hit_Critical_Fx");
        popUpFxPrefab = Resources.Load<GameObject>("Prefabs/Fx/PopUp");
        hitFxPrefab = Resources.Load<GameObject>("Prefabs/Fx/HitFx");
        hitMaterial = Resources.Load<Material>("Prefabs/Materials/flash_fx_mat");
    }

    protected virtual void Start()
    {
        igniteFx = transform.Find("IgniteFx")?.GetComponent<ParticleSystem>();
        chillFx = transform.Find("ChillFx")?.GetComponent<ParticleSystem>();
        shockFx = transform.Find("ShockFx")?.GetComponent<ParticleSystem>();
    }
    public void CreatePopUp(string content, Color color = default)
    {
        Vector3 positionOffset = new(0, 2.4f, 0);
        GameObject obj = Instantiate(popUpFxPrefab, transform.position + positionOffset, Quaternion.identity);
        PopUpFx popUpFx = obj.GetComponent<PopUpFx>();
        popUpFx.Tmp.text = content;
        popUpFx.Tmp.color = color == default ? Color.white : color;
    }

    protected IEnumerator FlashFX()
    {
        Sr.material = hitMaterial;
        Color originalColor = Sr.color;
        Sr.color = Color.white;
        yield return new WaitForSeconds(flashDuration);
        Sr.color = originalColor;
        Sr.material = originalMaterial;
    }

    protected void RedColorBlink() => Sr.color = Sr.color == Color.white ? Color.red : Color.white;

    protected void CancelColorChange()
    {
        CancelInvoke();
        Sr.color = Color.white;
        igniteFx.Stop();
        chillFx.Stop();
        shockFx.Stop();
    }

    public void IgniteFxFor(float seconds)
    {
        igniteFx.Play();
        InvokeRepeating(nameof(IgniteColorsFX), 0, 0.3f);
        Invoke(nameof(CancelColorChange), seconds);
    }

    public void ChillFxFor(float seconds)
    {
        chillFx.Play();
        InvokeRepeating(nameof(ChillColorsFX), 0, 0.3f);
        Invoke(nameof(CancelColorChange), seconds);
    }

    public void ShockFxFor(float seconds)
    {
        shockFx.Play();
        InvokeRepeating(nameof(ShockColorsFX), 0, 0.3f);
        Invoke(nameof(CancelColorChange), seconds);
    }

    public void MakeTransprent(bool isTransprent)
    {
        if (isTransprent)
        {
            hpBar.SetActive(false);
            Sr.color = Color.clear;
        }
        else
        {
            hpBar.SetActive(true);
            Sr.color = Color.white;
        }
    }

    public void CreateHitFX(Transform targetTransform, bool critical)
    {
        float zRotation = UnityEngine.Random.Range(-90, 90);
        float xPositionOffset = UnityEngine.Random.Range(-0.3f, 0.3f);
        float yPositionOffset = UnityEngine.Random.Range(-0.3f, 0.3f);
        Vector3 positionOffset = new(xPositionOffset, yPositionOffset, 0);
        quaternion rotation;
        GameObject prefab;
        if (critical)
        {
            prefab = hitCriticalFxPrefab;
            float yRotation = 0;
            zRotation = UnityEngine.Random.Range(-45, 45);
            if (entity.FacingDirection == -1)
                yRotation = 180;
            rotation = quaternion.Euler(new Vector3(0, yRotation, zRotation));
        }
        else
        {
            rotation = quaternion.Euler(0, 0, zRotation);
            prefab = hitFxPrefab;
        }
        GameObject obj = Instantiate(prefab, targetTransform.position + positionOffset, Quaternion.identity);
        if (critical)
            obj.transform.localScale = new Vector3(entity.FacingDirection, 1f, 1f);
        float destroyTime = obj.GetComponent<Animator>().GetCurrentAnimatorStateInfo(0).length;
        Destroy(obj, destroyTime);
    }

    protected void IgniteColorsFX() => Sr.color = Sr.color != igniteColors[0] ? igniteColors[0] : igniteColors[1];

    protected void ChillColorsFX() => Sr.color = Sr.color != chillColor[0] ? chillColor[0] : chillColor[1];

    protected void ShockColorsFX() => Sr.color = Sr.color != shockColors[0] ? shockColors[0] : shockColors[1];
}
